package com.gnerv.sylvanas.module.sse.storage;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Service
@AllArgsConstructor
public class SseStorageService {

    private static final Map<String, SseEmitter> SSE_EMITTER_MAP = new ConcurrentHashMap<>();
    private static final Map<String, List<String>> TOPIC_SUBSCRIBE_MAP = new ConcurrentHashMap<>();

    public void insertSseEmitter(String clientId, SseEmitter sseEmitter) {
        SSE_EMITTER_MAP.put(clientId, sseEmitter);
    }

    public void insertSubscribe(String clientId, List<String> topicList) {
        for (String topic : topicList) {
            List<String> subscribeList = TOPIC_SUBSCRIBE_MAP.get(topic);
            if (CollectionUtils.isEmpty(subscribeList)) {
                subscribeList = new ArrayList<>();
            }
            if (!subscribeList.contains(clientId)) {
                subscribeList.add(clientId);
            }
            TOPIC_SUBSCRIBE_MAP.put(topic, subscribeList);
        }
    }

    public void deleteSubscribe(String clientId, List<String> topicList) {
        for (String topic : topicList) {
            List<String> subscribeList = TOPIC_SUBSCRIBE_MAP.get(topic);
            if (CollectionUtils.containsInstance(subscribeList, clientId)) {
                subscribeList.remove(clientId);
            }
        }
    }

    public void deleteSseEmitter(String clientId) {
        SSE_EMITTER_MAP.remove(clientId);
        for (List<String> value : TOPIC_SUBSCRIBE_MAP.values()) {
            if (CollectionUtils.isEmpty(value)) {
                continue;
            }
            value.remove(clientId);
        }
    }

    public SseEmitter selectSseEmitter(String clientId) {
        return SSE_EMITTER_MAP.get(clientId);
    }

    public List<SseEmitter> selectListSseEmitterByTopic(String topic) {
        List<SseEmitter> sseEmitterList = new ArrayList<>();
        List<String> clientIdList = TOPIC_SUBSCRIBE_MAP.get(topic);
        for (String clientId : clientIdList) {
            SseEmitter sseEmitter = SSE_EMITTER_MAP.get(clientId);
            if (sseEmitter != null) {
                sseEmitterList.add(sseEmitter);
            }
        }
        return sseEmitterList;
    }

    public SseEmitter selectSseEmitterByClientIdAndTopic(String clientId, String topic) {
        List<String> clientIdList = TOPIC_SUBSCRIBE_MAP.get(topic);
        if (CollectionUtils.containsInstance(clientIdList, clientId)) {
            return SSE_EMITTER_MAP.get(clientId);
        }
        return null;
    }

    public Map<String, SseEmitter> getSseEmitterMap() {
        return SSE_EMITTER_MAP;
    }

    public Map<String, List<String>> getTopicSubscribeMap() {
        return TOPIC_SUBSCRIBE_MAP;
    }
}
